package com.douqu.game.core.entity.ext.data.major;

import com.bean.core.buffer.ByteBuffer;
import com.douqu.game.core.config.StableDataConfig;
import com.douqu.game.core.config.VipConfig;
import com.douqu.game.core.config.common.CommonData;
import com.douqu.game.core.config.common.GoodsData;
import com.douqu.game.core.config.major.MajorConfig;
import com.douqu.game.core.e.E_StableDataType;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.db.PropDB;
import com.douqu.game.core.entity.ext.BagInfo;
import com.douqu.game.core.entity.ext.data.BaseData;
import com.douqu.game.core.entity.world.WorldCollectBean;
import com.douqu.game.core.entity.world.WorldCollectData;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.factory.WorldInfoFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author wangzhenfei
 *         2017-10-18 18:38
 *         个人的采集信息
 */
public class CollectData extends BaseData {
    /**
     * 采集等级
     */
    private int level;

    /**
     * 当天采集次数
     */
    private int hasCollectTimes;

    /**
     * 当天最大采集次数
     */
    private int maxCollectTimes;

    /**
     * 当天已经抢夺次数
     */
    private int hasGrabTimes;

    /**
     * 当天最大抢夺次数
     */
    private int maxGrabTimes;

    /**
     * 被抢夺记录<流水号_抢夺时间， 物品>
     */
    private Map<String, List<GoodsData>> beGrabRecord = new ConcurrentHashMap<>();

    /**
     * 上一次记录时间
     */
    private long lastRecordTime;

    private List<GoodsData> cacheBattleGoods;




    private Player player;

    public CollectData(Player player)
    {
        this.player = player;
    }

    @Override
    public void init()
    {
        reset();
    }

    @Override
    public void checkInit() {
        if(level == 0){
            calculateLevel();
        }
    }


    @Override
    public void reset()
    {

        hasCollectTimes = 0;
        maxCollectTimes = ((VipConfig)(DataFactory.getInstance().getGameObject(DataFactory.VIP_KEY,
                player.getVipLevel()))).dailyCollectTimes;
        hasGrabTimes = 0;
        maxGrabTimes = ((StableDataConfig)(DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
                E_StableDataType.COLLECT_GRAB_BASE_TIMES.getCode()))).intValue;
        lastRecordTime = DataFactory.currentTime;
        beGrabRecord.clear();
    }

    @Override
    public void checkReset() {
        if(!CoreUtils.isTodayByOffset(lastRecordTime, DataFactory.currentTime, ConstantFactory.DEFAULT_RESET_FRESH_TIMES_HOUR)){
            reset();
        }
    }


    @Override
    public void writeTo(ByteBuffer buffer)
    {
        buffer.writeShort(level);
        buffer.writeShort(hasCollectTimes);
        buffer.writeShort(maxCollectTimes);
        buffer.writeShort(hasGrabTimes);
        buffer.writeShort(maxGrabTimes);
        buffer.writeLong(lastRecordTime);

        buffer.writeShort(beGrabRecord.size());
        for(Map.Entry<String, List<GoodsData>> entry : beGrabRecord.entrySet())
        {
            buffer.writeUTF(entry.getKey());
            buffer.writeShort(entry.getValue().size());
            for(GoodsData data : entry.getValue())
            {
                buffer.writeInt(data.type);
                buffer.writeInt(data.id);
                buffer.writeInt(data.value);
            }
        }

        buffer.writeBoolean(false);

    }

    @Override
    public void loadFrom(ByteBuffer buffer)
    {
        level = buffer.readShort();
        hasCollectTimes = buffer.readShort();
        maxCollectTimes = buffer.readShort();
        hasGrabTimes = buffer.readShort();
        maxGrabTimes = buffer.readShort();
        lastRecordTime = buffer.readLong();
        int size = buffer.readShort();
        for(int i = 0; i < size; i++){
            String key = buffer.readUTF();
            int listSize = buffer.readShort();
            List<GoodsData> dataList = new ArrayList<>();
            for(int j = 0;j < listSize; j++){
                GoodsData data = new GoodsData(buffer.readInt(), buffer.readInt(), buffer.readInt());
                if(!data.checkGoods()){
                    LogUtils.error("读取物品错误：" + data.toString());
                }
                dataList.add(data);
            }
            beGrabRecord.put(key, dataList);
        }
        buffer.readBoolean();
        calculateLevel();
    }

    public  GoodsData[] removeRecord(String key) {
        if(!isRecordExist(key)){
            return null;
        }
        List<GoodsData> list = beGrabRecord.get(key);
        beGrabRecord.remove(key);
        GoodsData[] goodsDatas = new GoodsData[list.size()];
        for(int i =0; i < list.size(); i++){
            goodsDatas[i] = list.get(i);
        }
        return goodsDatas;
    }

    public boolean isRecordExist(String key){
        return beGrabRecord.get(key) != null;
    }

    /**
     * 增加当日最大采集次数
     */
    public void addMaxCollectTimes(int times){
        maxCollectTimes += times;
    }

    /**
     * 增加抢夺记录
     * @param objectIndex
     * @param goodsDatas
     * @return
     */
    public boolean addBeGrabRecord(String objectIndex, List<GoodsData> goodsDatas){
        if(goodsDatas != null && !StringUtils.isNullOrEmpty(objectIndex)){
            List<GoodsData> temp = new ArrayList<>();
            for(GoodsData data : goodsDatas){
                temp.add(data.copy());
            }
            beGrabRecord.put(objectIndex + ConstantFactory.UNDERLINE + DataFactory.currentTime, temp);
            return true;
        }
        return false;
    }

    public boolean hasRedPointRemind() {
        WorldCollectData worldCollectData = WorldInfoFactory.getInstance().getWorldCollectData();
        WorldCollectBean myCollectBean = worldCollectData.getCollectPlayerByObjectIndex(player.getObjectIndex());
        if(myCollectBean != null){
            if(!myCollectBean.isTimeIn()){
                //采集物品未领取
                return true;
            }
        }else  {
            if(getRemainCollectTimes() > 0){
                return true;
            }
        }

        if(getRemainGrabTimes() > 0){
            return true;
        }
        return false;
    }

    public void addCollectTimes(){
        lastRecordTime = DataFactory.currentTime;
        if(hasCollectTimes <= maxGrabTimes){
            hasCollectTimes++;
        }
    }

    public void addGrabTimes(){
        lastRecordTime = DataFactory.currentTime;
        if(hasGrabTimes <= maxGrabTimes){
            hasGrabTimes++;
        }
    }

    public int getLevel() {
        if(level == 0){
            calculateLevel();
        }
        return level;
    }

    public int getMaxCollectTimes() {
        return maxCollectTimes;
    }

    public int getMaxGrabTimes() {
        return maxGrabTimes;
    }

    public int getRemainCollectTimes(){
        if(hasCollectTimes > maxCollectTimes){
            hasCollectTimes = maxCollectTimes;
        }
        return maxCollectTimes - hasCollectTimes;
    }

    public int getRemainGrabTimes(){
        if(hasGrabTimes > maxGrabTimes){
            hasGrabTimes = maxGrabTimes;
        }
        return maxGrabTimes - hasGrabTimes;
    }


    public List<WorldCollectBean> getRevengePlayer()
    {
        List<WorldCollectBean> list = new ArrayList<>();
        for(Map.Entry<String, List<GoodsData>> entry : beGrabRecord.entrySet())
        {
            list.add(new WorldCollectBean(entry.getKey(), entry.getValue()));
        }
        return list;
    }

    /**
     *   是否采集过
     */
    public boolean isMajor(){
        StableDataConfig config = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.COLLECT_PRODUCT_EXP.getCode());
        BagInfo bagInfo = player.getExtInfo(BagInfo.class);
        int count = bagInfo.getGoodsCount(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE, config.goods[0].id);
        if (count > 0){
            return true;
        }
        return false;

    }

    /**
     * 重新计算等级
     */
    public void calculateLevel() {
        StableDataConfig config = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.COLLECT_PRODUCT_EXP.getCode());
        BagInfo bagInfo = player.getExtInfo(BagInfo.class);
        int count = bagInfo.getGoodsCount(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE, config.goods[0].id);
        List<MajorConfig> majorConfigs = DataFactory.getInstance().getDataList(DataFactory.MAJOR_KEY);
        int end = majorConfigs.size();
        int tempLv = 0;
        for(int i = 0; i < end; i++)
        {
            if(count < majorConfigs.get(i).collectExp)
                break;
            tempLv = majorConfigs.get(i).id;
        }

        //重新计算等级后 使用新的等级
        this.level = tempLv;
    }


    /**
     * 吃草吃药获得采集经验和炼制经验 TODO 未调试
     * @param type 类型9药草10药水
     * @param quality 品质
     */
    public boolean addExpByType(int type,int quality){
        BagInfo bagInfo = player.getExtInfo(BagInfo.class);
        //吃药草
        int addExp = 0;
        int qualityExp = 0;
        List<PropDB> list=  bagInfo.getTypePropList(type);
        CommonData[] commons;
        StableDataConfig stableDataConfig;
        //吃草
        if (type == ConstantFactory.PROP_TYPE_GRASS){
            stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
                    E_StableDataType.EAT_GRASS_ADD_EXP.getCode());
        }
        //吃药
        else if (type == ConstantFactory.PROP_TYPE_LIQUID){
            stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
                    E_StableDataType.EAT_DRUG_ADD_EXP.getCode());
        }
        else{
            return false;
        }
        if (stableDataConfig == null){
            LogUtils.error("StableDataConfig error ->" + "no have type "
                    + E_StableDataType.EAT_GRASS_ADD_EXP.getMsg());
            return false;
        }
        commons= stableDataConfig.commons;
        for (CommonData data:commons){
            if (data.id == quality){
                qualityExp = data.value;
                break;
            }
        }
        if (qualityExp == 0){
            LogUtils.error("StableDataConfig error ->" + "no have quality: "+
                    quality+" type:" + E_StableDataType.EAT_GRASS_ADD_EXP.getMsg());
            return false;
        }
        for (PropDB db:list){
            addExp +=  db.count * qualityExp;
            bagInfo.addProp(db.id, -db.count);
        }
        bagInfo.addGoods(new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE,
                stableDataConfig.intValue, addExp), true);


        return true;
    }


    public List<GoodsData> getCacheBattleGoods() {
        return cacheBattleGoods == null ? cacheBattleGoods = new ArrayList<>() : cacheBattleGoods;
    }

    public void addNewBattleToCache(List<GoodsData> list){
        getCacheBattleGoods().clear();
        if(list != null){
            getCacheBattleGoods().addAll(list);
        }
    }

    public int getHasCollectTimes() {
        return hasCollectTimes;
    }
}
